const massage = title => {
	uni.showToast({
		title,
		icon: 'none',
		duration: 2000,
		mask: false,
	});
}

/**
 * 对象颠倒
 * @param  {Object}  data                                   参数对象，必须
 */
const reverseObj = data => {
	let arr = [],
		obj = {};
	for (let key in data) {
		arr.push([data[key], key]); // [[value1, key1], [value2, key2]...]
	};
	arr.reverse(); // [[value100, key100], [value99, key99]...]

	arr.forEach(item => {
		let key = item[1],
			val = item[0]
		obj[key] = val
	})
	return obj;
}
/**
 * 表单验证
 * @param  {Object}  data                                   参数对象，必须
 * @param  {Object}  rules                                  验证规则，必须(验证判断顺序是依据 rules 传入顺序执行)
 * @param  {Function}  cb                                   回调函数，必须
 */
const verification = (data, rules, cb) => {
	rules = reverseObj(rules) // 验证判断顺序是依据 rules 传入顺序执行
	const regulars = {
		intNumber: /^[1-9]*[1-9][0-9]*$/,
		phone: /^(13|14|15|17|18|19)\d{9}$/,
		isIdCard: /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/
	}
	const isNotMatch = (val, regex) => {
		return val.toString().search(regex) === -1;
	};
	const fieldList = Object.keys(rules),
		warnings = {};
	/**
	 * 验证判断
	 * @param  {String}  fieldValue                             字段值，必须
	 * @param  {String}  fieldKey                               字段名，必须
	 */
	const judge = (fieldValue, fieldKey) => {
		rules[fieldKey].map((item, index) => {
			if (fieldValue == undefined) return // 当 rules 字段和 data 字段不匹配时

			if (item.required) {
				!fieldValue.length &&
					(warnings[fieldKey + '-warning'] = true) &&
					massage(item.message) &&
					cb(false)
			}
			if (item.isNumber) {
				isNotMatch(fieldValue, regulars['intNumber']) &&
					(warnings[fieldKey + '-warning'] = true) &&
					massage(item.message) &&
					cb(false)
			}
			if (item.isPhone) {
				isNotMatch(fieldValue, regulars['phone']) &&
					(warnings[fieldKey + '-warning'] = true) &&
					massage(item.message) &&
					cb(false)
			}
			if (item.isIdCard) {
				isNotMatch(fieldValue, regulars['isIdCard']) &&
					(warnings[fieldKey + '-warning'] = true) &&
					massage(item.message) &&
					cb(false)
			}
			if (item.max) {
				fieldValue.length > item.max &&
					(warnings[fieldKey + '-warning'] = true) &&
					massage(item.message) &&
					cb(false)
			}
			if (item.min) {
				fieldValue.length < item.min &&
					(warnings[fieldKey + '-warning'] = true) &&
					massage(item.message) &&
					cb(false)
			}
		})
	}

	fieldList.forEach(async field => {

		if (field.includes('.')) { // 深数据结构
			let deepValue = ''
			const findDeepValue = (parent) => { // 层层递归直到找到底层数据值为止
				if (!genealogy[index]) {
					return deepValue
				}

				deepValue = parent[genealogy[index]];
				++index
				findDeepValue(deepValue)
			}
			let genealogy = field.split('.'), // 'obj1.obj2.attr' 类型切割成层级族谱
				index = 0;

			findDeepValue(data)

			judge(deepValue, field)
		} else { // 浅数据结构

			judge(data[field], field)
		}
	})
	const noWarning = Object.values(warnings).every(item => !item)
	noWarning && cb(true)
}

export default verification
